#include <iostream>

template <typename... Args>
void print(const Args &...args)
{
    ((std::cout << args << " "), ...);
    std::cout << std::endl;
}

class Shape
{
protected:
    double weight_;
    double height_;

public:
    Shape(double weight, double height)
        : weight_(weight),
          height_(height)
    {
    }
    virtual double getArea() const = 0;
    virtual ~Shape() {}

protected:
    void dosomething() const {}
};

class Triangle : public Shape
{
public:
    Triangle(double w, double h) : Shape(w, h) {}
    double getArea() const override
    {
        dosomething();
        return 0.5 * weight_ * height_;
    }
};

class Rectangle : public Shape
{

public:
    Rectangle(double w, double h) : Shape(w, h) {}
    double getArea() const override
    {
        return weight_ * height_;
    }
};

class Testclass
{
public:
    Testclass()
    {
        str1 = "hello";
        std::cout << "TestClass()" << std::endl;
    }
    void dosomething()
    {
        std::cout << "dosomething()" << std::endl;
    }

public:
    std::string str1;

protected:
    int val = 10;

private:
    double stu = 0.0;
};

// 这里public和protected的继承主要影响的是子类实例化的对象，是否还可以访问原来父类中的public属性
// 如果是public是没有影响的，使用protected继承后，原来父类中的public对象在子类中就变成了protected属性，无法再类外直接访问
// struct默认是public，class默认是private
class test : public Testclass
{
public:
    int x = 0;

public:
    test() : x(10)
    {
        str1 = "hello world";
    }
    void print1()
    {
        std::cout << val << std::endl;

        // std::cout << stu << std::endl;
    }
};
int main()
{
    Testclass test1;
    Rectangle r(10, 20);
    Triangle t(10, 20);
    std::cout << "r.getArea(): " << r.getArea() << std::endl;
    std::cout << "t.getArea(): " << t.getArea() << std::endl;
    test1.dosomething();
    test te;

    print(test1.str1);
    // print(te.str1);
    int i = 10;
    double x = i;
    // 继承关系为private时，下面这条语句会报错，这是因为继承关系被隐藏了，无法进行类型转换
    /*Testclass t1 = te;
    Testclass *t1 = &te;*/
    Testclass &t2 = te;
    // print("t2.x: ",t2.x);
    t2.str1 = "std::vetcor<int>";
    print("t2.str1: ", te.str1);

    // 这里产生了临时变量，临时变量具有常性，权限被放大了
    // double& s = i;

    // print("hello",10);
    return 0;
}
